package com.bc.trade.channel.hicard;

import java.util.List;
import java.util.Map;
import java.util.TreeMap;

import com.alibaba.fastjson.JSONObject;
import com.bc.common.CommonEnum.OrderStatus;
import com.bc.common.CommonEnum.Resp;
import com.bc.common.PayType;
import com.bc.common.message.AccountBalanceChangeResp;
import com.bc.common.message.AppidPayReq;
import com.bc.common.message.AppidPayResp;
import com.bc.common.message.DFReq;
import com.bc.common.message.DFResp;
import com.bc.trade.channel.IChannel;
import com.bc.trade.config.R;
import com.bc.trade.config.SystemConfig;
import com.bc.trade.message.QueryOrderResp;
import com.bc.trade.message.QuickPayReq;
import com.bc.trade.message.QuickPayResp;
import com.bc.trade.message.QuickPaySetReq;
import com.bc.trade.message.QuickPaySetResp;
import com.bc.trade.message.UnionPayReq;
import com.bc.trade.message.UnionPayResp;
import com.bc.trade.model.Account;
import com.bc.trade.model.Channel;
import com.bc.trade.model.TradeOrder;
import com.bc.trade.service.CalcFeeService;
import com.bc.trade.service.VirtualAccountService;
import com.fs.common.util.FSDate;
import com.fs.common.util.FSHttp;
import com.fs.common.util.FSJson;
import com.fs.common.util.FSLog;
import com.fs.common.util.FSMD5;
import com.jfinal.kit.StrKit;

public class HicardChannel implements IChannel {
	//private final String KEY = SystemConfig.channelConfig.get("hicard_key");
	private final String TRADE_URL = SystemConfig.channelConfig.get("hicard_create_url");
	private final String TRADE_QUERY_URL = SystemConfig.channelConfig.get("hicard_query_url");
	private final String TRADE_NOTIFY_URL = SystemConfig.channelConfig.get("hicard_notify_url");
	private final String VERSION = SystemConfig.channelConfig.get("hicard_version");
	//private final String ORGANNO = SystemConfig.channelConfig.get("hicard_organNo");
	private final String BIZTYPE = SystemConfig.channelConfig.get("hicard_bizType");
	
	private final String HICARD_FEE = SystemConfig.channelConfig.get("hicard_fee"); //汇卡手续费
	private final String HICARD_MIN_AMT = SystemConfig.channelConfig.get("hicard_min_amt");//汇卡最低手续费
	private final String hicard_that_amt = SystemConfig.channelConfig.get("hicard_that_amt"); //金额手续费低价判断
	
	
	//private static int XNum = 0;
	private static VirtualAccountService accountService = new VirtualAccountService();

	@Override
	public QueryOrderResp query(TradeOrder order) throws Exception {
		QueryOrderResp resp = new QueryOrderResp();
		TreeMap<String, String> map = new TreeMap<String, String>();
		map.put("version", VERSION);
		map.put("hicardMerchNo", order.getOtherMerchCode());
		String hkKEY = Account.dao.findHkKey(order.getOtherMerchCode());
		
		map.put("merchOrderNo", order.getOrderNo());
		map.put("hicardOrderNo", order.getChannelOrderNo());
		map.put("sign", FSMD5.sortSign(map, hkKEY).toLowerCase());

		try {
			String connext = FSJson.toString(map);
			FSLog.api.info("查询接口上送汇卡数据:" + connext);
			String result = FSHttp.postJson(TRADE_QUERY_URL, FSJson.toString(map));
			FSLog.api.info("查询接口汇卡响应数据:" + result);

			Map<String, String> resmap = FSJson.toMap(result);

			String respCode = resmap.get("respCode");
			String payTime = resmap.get("payTime");

			FSLog.api.info("汇卡查询通知订单：" + order.toString());
			if ("00".equals(respCode)) {
				// 更新虚账账户额度，内部系统发时才调用
				if (order.getCustomerName().equals(PayType.OWER_QUERY)) {
					if (StrKit.notBlank(payTime) && payTime.length() == 19) {
						String time = payTime.substring(11, 19);
						if (time.compareTo("09:00:00") >= 0 && time.compareTo("21:30:00") <= 0) {
							order.setIsD0(false);// 入到T1余额
						} else {
							order.setIsD0(true);// 入到D0余额
						}
					}

					AccountBalanceChangeResp accountResp = accountService.processVirtualAccount(order);
					if (accountResp != null) {
						order.setBalance(Long.valueOf(accountResp.getBalance()));
						order.setIsInVirtualAccount(true);

						// 再入到汇卡商户号对应的虚账上
						CalcFeeService calc = new CalcFeeService();
						Integer channelFee = calc.calcResult(order.getAmount(), HICARD_FEE, 0, 0);
						if(order.getAmount() <= Integer.parseInt(hicard_that_amt)) {
							channelFee = Integer.parseInt(HICARD_MIN_AMT);
						}
						AccountBalanceChangeResp hicardAccountResp = accountService.addMoney(order.getIsD0(), "hicard",
								order.getOtherMerchCode(), order.getAmount() - channelFee);
						if (hicardAccountResp != null) {
							FSLog.task.info("订单号" + order.getOrderNo() + "入汇卡商户号对应的虚账成功。");
						}

					}

					order.setCustomerName("");
				}

				order.setPayTime(payTime);
				order.setRespCode(Resp.Success.getCode());
				order.setRespMsg(Resp.Success.getMsg());
				order.setOrderStatus(OrderStatus.Success.getValue());
				order.setSettleDate(Channel.findSettleDate(order));

				resp.setPayTime(payTime);
				resp.setOriginalRespCode(Resp.Success.getCode());
				resp.setOriginalRespMsg(Resp.Success.getMsg());
				resp.setCodeAndMsg(Resp.Success.getCode(), Resp.Success.getMsg());
			} else if ("99".equals(respCode)) {
				order.setRespCode(Resp.InProcess.getCode());
				order.setRespMsg(resmap.get("respMsg"));
				order.setOrderStatus(OrderStatus.InProcess.getValue());

				resp.setOriginalRespCode(Resp.InProcess.getCode());
				resp.setOriginalRespMsg(Resp.InProcess.getMsg());
				resp.setCodeAndMsg(Resp.InProcess.getCode(), Resp.InProcess.getMsg());
			} else {
				order.setRespCode(Resp.Fail.getCode());
				order.setRespMsg(resmap.get("respMsg"));
				order.setOrderStatus(OrderStatus.Fail.getValue());

				resp.setOriginalRespCode(Resp.Fail.getCode());
				resp.setOriginalRespMsg(Resp.Fail.getMsg());
				resp.setCodeAndMsg(Resp.Fail.getCode(), Resp.Fail.getMsg());

			}
			FSLog.api.info("处理完成订单：" + order.toString());
			order.update();
		} catch (Exception e) {
			FSLog.api.error("hicard交易查询异常:" + e);
			resp.setCodeAndMsg(Resp.InProcess.getCode(), Resp.InProcess.getMsg());
		}
		return resp;
	}

	/**
	 * 支付宝生活号及微信公众号支付
	 * 
	 * @param req
	 * @param order
	 * @return
	 * @throws Exception
	 */
	@Override
	public AppidPayResp appidPay(AppidPayReq req, TradeOrder order,String hkOrgCode) throws Exception {
		AppidPayResp resp = new AppidPayResp(req);
		TreeMap<String, String> map = new TreeMap<String, String>();
		String hkKEY = null;
		map.put("version", VERSION);
		
		// 汇卡商户号限额10w
		long sumAmount = 0;
		
		//选出虚账余额最小的 汇卡商户号作为本次交易的上游商户号
		Account hicardMerchant = Account.dao.findMinHKBanlance(hkOrgCode);
		
		FSLog.api.info(Thread.currentThread().getId() + "本次使用的汇卡商户号:" + "-----------" + hicardMerchant.getAccountNo());
		order.setOtherMerchCode(hicardMerchant.getAccountNo());// 汇卡商户号, 查询接口需要使用
		order.setCustomerName(hicardMerchant.getAccountName());
		sumAmount = TradeOrder.dao.sumAmount(hicardMerchant.getAccountNo(), FSDate.getDate());
		if ((sumAmount + order.getAmount()) > hicardMerchant.getHkMaxFee()) {
			return resp.setCodeAndMsg(Resp.Fail.getCode(), "超出渠道限额");
		}
		
		map.put("hicardMerchNo", hicardMerchant.getAccountNo());
		map.put("organNo", hicardMerchant.getHkOrgCode());
		hkKEY = hicardMerchant.getHkSafeKey();
		
		if (PayType.ALIPAY_PUBLIC.equals(req.getPayType())) {
			map.put("payType", "027");// 支付宝生活号
		}
		if (PayType.ALIPAY_QRCODE.equals(req.getPayType())) {
			map.put("payType", "009");// 支付宝二维码
		}
		if (PayType.WECHAT_PUBLIC.equals(req.getPayType())) {
			map.put("payType", "014");// 微信公众号
		}
		if (PayType.WECHAT_QRCODE.equals(req.getPayType())) {
			map.put("payType", "011");// 微信二维码
		}
		map.put("isT0", "1");
		map.put("bizType", BIZTYPE);
		map.put("merchOrderNo", order.getOrderNo());
		map.put("amount", req.getAmount());
		map.put("backEndUrl", TRADE_NOTIFY_URL);
		if (StrKit.notBlank(req.getCallbackUrl())) {
			map.put("frontEndUrl", req.getCallbackUrl());
		}
		map.put("sign", FSMD5.sortSign(map, hkKEY).toLowerCase());
		String sendData = FSJson.toString(map);
		FSLog.api.info("交易请求汇卡数据：" + sendData);
		try {
			String result = FSHttp.postJson(TRADE_URL, sendData);
			FSLog.api.info("交易汇卡响应数据:" + result);

			JSONObject json = JSONObject.parseObject(result);

			order.setChannelOrderNo(json.getString("hicardOrderNo"));

			if ("00".equals(json.getString("respCode"))) {
				if (PayType.ALIPAY_PUBLIC.equals(order.getPayType())
						|| PayType.WECHAT_PUBLIC.equals(order.getPayType())) {
					resp.setPayInfo(json.getString("payInfo"));
				}
				if (PayType.ALIPAY_QRCODE.equals(order.getPayType())
						|| PayType.WECHAT_QRCODE.equals(order.getPayType())) {
					resp.setPayInfo(json.getString("qrURL"));
				}
				resp.setCodeAndMsg(Resp.Success.getCode(), Resp.Success.getMsg());
			} else {
				resp.setPayInfo("");
				resp.setCodeAndMsg(Resp.Fail.getCode(), Resp.Fail.getMsg());
			}
		} catch (Exception e) {
			e.printStackTrace();
		}

		return resp;
	}

	@Override
	public QueryOrderResp dfQuery(TradeOrder order) throws Exception {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public DFResp df(DFReq req, TradeOrder order) throws Exception {
		DFResp rsp = new DFResp(req);
		order.setOrderStatus(OrderStatus.InProcess.getValue());
		order.setRespCode(Resp.Success.getCode());
		order.setRespMsg(Resp.Success.getMsg());
		rsp.setRespCode(Resp.Success.getCode());
		rsp.setRespMsg(Resp.Success.getMsg());
		return rsp;
	}

	@Override
	public UnionPayResp unionpay(UnionPayReq req, TradeOrder order) throws Exception {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public QuickPaySetResp quickPaySet(QuickPaySetReq req, TradeOrder order) throws Exception {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public QuickPayResp quickPay(QuickPayReq req, TradeOrder order) throws Exception {
		// TODO Auto-generated method stub
		return null;
	}
}
